home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 003 / dbapg.arc / DISKSTAT.ASM < prev    next >
Encoding:
Assembly Source File  |  1984-08-05  |  12.5 KB  |  293 lines

  1. ; Subroutine.: DISKSTAT.ASM
  2. ; Author.....: Kelly Mc Tiernan
  3. ; Date.......: 1983
  4. ; Notice.....: Copyright 1983, Kelly Mc Tiernan, All Rights Reserved
  5. ; Notes......: CP/M-80 disk drive status routine.
  6. ;
  7. BDOS    EQU     00005H
  8. FDPB    EQU     1FH
  9. FALV    EQU     1BH
  10. FDSK    EQU     19H
  11. FCHG    EQU     0EH
  12. ;
  13.         ORG     42000
  14. ;
  15. START:  SHLD    SAVEHL          ; SAVE HL REG PAIR
  16.         MVI     C,FDSK          ; DETERMINE CURRENT DISK 
  17.         PUSH    H               ; SAVE HL 
  18.         CALL    BDOS            ; 
  19.         STA     SAVDSK          ; AND SAVE TO RESTORE
  20.         POP     H               ; GET IT BACK
  21.         INX     H               ; POINT TO FIRST BYTE OF VARIABLE
  22.         MOV     A,M             ; GET IT
  23.         ORA     A               ; CLEAR CARRY
  24.         SBI     41H             ; CONVERT ASCII A,B,C TO 0,1,2,..
  25.         CPI     10H             ; LEGAL DRIVE NAME?
  26.         JNC     KEEPDR          ; NO, KEEP CURRENT DRIVE
  27.         MOV     E,A             ; GET DRIVE TO SELECT
  28.         MVI     C,FCHG          ; SELECT FUNCTION
  29.         CALL    BDOS            ;
  30. ;
  31. KEEPDR: LXI     H,0000H         ; TO SAVE SP
  32.         DAD     SP              ; GET SP
  33.         SHLD    SAVESP          ; SAVE IT
  34.         MVI     A,01H           ; TO INIT. SIG. DIGIT POINTER
  35.         LXI     H,ANSWER        ; WHERE IT GOES
  36.         MOV     M,A             ; INITIALIZE
  37.         MVI     C,FDPB          ; GET DPB ADDRESS
  38.         CALL    BDOS            ; HL HAS ADDRESS
  39.         SHLD    DPBADR          ; SAVE BASE ADDRESS
  40.         LXI     B,0005H         ; OFFSET TO DSM
  41.         DAD     B               ; 
  42.         MOV     E,M             ; GET FIRST BYTE
  43.         INX     H               ; FOR NEXT BYTE
  44.         MOV     D,M             ; GET IT
  45.         XCHG                    ; GET WHERE IT CAN BE USED
  46.         MVI     B,03H           ; COUNT FOR SHIFT
  47. DIV8:   ORA     A               ; CLEAR CARRY FOR DIVISION
  48.         MOV     A,H             ; GET FIRST BYTE
  49.         RAR                     ; DIVIDE BY 2
  50.         MOV     H,A             ; RESTORE HIGH BYTE
  51.         MOV     A,L             ; GET LOW BYTE
  52.         RAR                     ; DIVIDE BY 2 (SHIFT IN HB CARRY)
  53.         MOV     L,A             ; RESTORE IT
  54.         DCR     B               ; FOR COUNT
  55.         JNZ     DIV8            ; CONTINUE 3 TIMES (2*2*2=8)è        INX     H               ; +1=ALV LENGTH
  56.         SHLD    ALVLNG          ; SAVE LENGTH OF ALV
  57. ;
  58. ; NOW CALCULATE BLOCK SIZE FOR DRIVE
  59. ;
  60.         LHLD    DPBADR          ; GET BACK BLOCK ADDRESS
  61.         INX     H               ; VECTOR INTO DPB FOR BSH
  62.         INX     H               ;
  63.         MOV     E,M             ; GET IT
  64.         MVI     D,00H           ; ZERO HB
  65.         DCX     D               ; FOR VECTOR INTO TABLE
  66.         DCX     D               ;
  67.         DCX     D               ;
  68.         MOV     A,E             ; GET IT
  69.         ORA     A               ; CLEAR CARRY
  70.         RAL                     ; MULTIPLY BY 2
  71.         MOV     E,A             ; GET BACK VECTOR 
  72.         LXI     H,TABLE         ; BASE ADDRESS
  73.         DAD     D               ; ADD IN VECTOR
  74.         MOV     E,M             ; GET LB (STORED LB,HB)
  75.         INX     H               ; NEXT BYTE
  76.         MOV     D,M             ; DE NOW CONTAINS BLOCK SIZE
  77.         XCHG                    ; GET IT TO WHERE WE CAN SAVE IT
  78.         SHLD    BLS             ; SAVE IT
  79. ;
  80. ;
  81. ; NOW LET'S DETERMINE SPACE LEFT ON DISK
  82. ;
  83.         MVI     C,FALV          ; LET'S GET ALV ADDRESS NOW
  84.         CALL    BDOS            ; HL CONTAINS ADDRESS
  85.         LDA     ALVLNG          ; GET LENGTH
  86.         MOV     B,A             ; INTO COUNTER 1
  87.         LXI     D,0000H         ; BIT COUNTER ZEROED
  88.         DCX     H               ; SET FOR LOOP CONTROL
  89.         SHLD    TEMP            ; SAVE HL
  90.         DI                      ; DISABLE INTERRUPTS BEFORE SP 
  91.                                 ; CHANGE
  92.         LHLD    BLS             ; GET BLOCK SIZE
  93.         SPHL                    ; FOR ADDITION
  94.         LXI     H,0000H         ; INITIALIZE
  95.         SHLD    SIZE0           ;   "   "
  96.         SHLD    SIZE1           ;   "   "
  97. BITCNT: LHLD    TEMP            ; RESTORE HL
  98.         INX     H               ; POINT TO BYTE
  99.         MVI     C,08H           ; COUNTER 2 FOR BITS/BYTE
  100.         MOV     A,M             ; GET FIRST BYTE
  101.         ORA     A               ; CLEAR CARRY
  102.         SHLD    TEMP            ; SAVE HL POINTER
  103. BIT1:   LHLD    SIZE0           ; GET LOW WORD TOTAL
  104.         RAR                     ; ROTATE A TO COUNT ZERO BITS
  105.         JC      BIT2            ; DON'T COUNT 1'S
  106.         DAD     SP              ; IF UNALLOC. THEN ADD 1 BLOCK 
  107.                                 ; TO TTL.
  108.         JNC     BIT2            ; IF NO CARRY FROM DAD H
  109.         INX     D               ; ELSE ADD 1 TO HIGH WORDèBIT2:   SHLD    SIZE0           ; SAVE NEW LOW WORD FOR UNALLOC.
  110.         DCR     C               ; COUNTER
  111.         JNZ     BIT1            ; NEXT BIT
  112.         DCR     B               ; COUNT FOR BYTES
  113.         JNZ     BITCNT          ; DO NEXT BYTE
  114.         XCHG                    ; GET HIGH WORD INTO HL
  115.         SHLD    SIZE1           ; SAVE IT
  116.         LHLD    SIZE0           ; FOR CORRECTION FACTOR
  117.         LXI     SP,0E000H       ; ERROR OFFSET
  118.         DAD     SP              ; TWO'S COMP. OF 2000H (SUBTRACT
  119.                                 ; OFFSET)
  120.         SHLD    SIZE0           ; SAVE RESULT
  121.         JC      EX1             ; EXIT IF CARRY (LOW WORD > 
  122.                                 ; 2000H)
  123.         LHLD    SIZE1           ; FOR BORROW
  124.         DCX     H               ; SUBTRACT 1
  125.         SHLD    SIZE1           ; SAVE RESULT 
  126. EX1:    LHLD    SAVESP          ; RESTORE STACK POINTER
  127.         SPHL                    ;
  128.         EI                      ; ENABLE INTERRUPTS 
  129. ;
  130. ;
  131. ; NOW WE CONVERT TO A DECIMAL STRING
  132. ;
  133.         LXI     H,ANSWER+1      ; TO INITIAIZE DATA AREA
  134.         MVI     B,0AH           ; COUNTER
  135.         MVI     A,00H           ; INITIALIZE TO 0
  136. INIT1:  MOV     M,A             ; 
  137.         INX     H               ; NEXT BYTE
  138.         DCR     B               ;
  139.         JNZ     INIT1           ; REPEAT FOR 10 BYTES
  140.         MVI     C,0AH           ; TOTAL # OF SIG DIGITS COUNTER
  141.         LXI     H,SIZE0         ; POINTER TO LOWEST BYTE
  142.         XCHG                    ; SAVE IT
  143.         LXI     H,TBL2          ; POINT TO SUBTRACTION TABLE
  144.         XCHG                    ; GET BACK DATA TABLE ADDRESS
  145. MINUS:  ORA     A               ; CLEAR CARRY FOR LOW BYTE
  146.         MVI     B,03H           ; COUNTER FOR SUBS
  147. MIN0:   MOV     A,M             ; GET DATA
  148.         XCHG                    ; GET SUB TABLE POINTER
  149.         SBB     M               ; SUBTRACT DIGIT
  150.         INX     H               ; POINT TO NEXT TABLE ENTRY
  151.         XCHG                    ; GET BACK DATA POINTER
  152.         MOV     M,A             ; PUT BACK RESULT
  153.         INX     H               ; POINT TO NEXT DATA BYTE
  154.         DCR     B               ; DONE WITH LOW 3 BYTES ?
  155.         JNZ     MIN0            ; CHECK FOR NEG ON LAST BYTE SBB
  156. LAST1:  MOV     A,M             ; GET MOST SIG BYTE
  157.         XCHG                    ; GET TABLE POINTER
  158.         SBB     M               ; SUBTRACT IT
  159.         DI                      ; DISABLE INTERUPTS BEFORE CALL
  160.         CP      AD1             ; ADD 1 TO SIG DIGIT IF IT WENT
  161.         EI                      ; ENABLE INTERUPTS ON RETURN
  162.         DCX     H               ; MOVE POINTER BACK TO BEGINNING
  163.         DCX     H               ; OF TABLEè        DCX     H               ;
  164.         XCHG                    ; GET BACK DATA POINTER
  165.         MOV     M,A             ; PUT BACK RESULT
  166.         DCX     H               ; MOVE POINTER BACK TO BEGINNING 
  167.         DCX     H               ; OF DATA
  168.         DCX     H               ; 
  169.         DI                      ; DISABLE INTERUPTS
  170.         CM      PUTBK           ; PUT BACK IF NEG AND MOVE ON
  171.         EI                      ; ENABLE INTERUPTS
  172.         DCR     C               ; ONLY TO OVERRIDE SBB M
  173.         INR     C               ;
  174.         JNZ     MINUS           ; NO, DO AGAIN
  175. ;
  176. ;
  177. ; NOW LETS CONVERT TO ASCII (ADD 30H) AND PASS BACK
  178. ; TO 10 DIGIT DBASE VARIABLE 
  179. ;
  180.         LXI     H,ANSWER+1      ; POINT TO ANSWER BUFFER
  181.         MVI     B,0AH           ; FOR ALL 10 BYTES
  182. FILL:   MVI     A,30H           ; TO CONVERT TO ASCII
  183.         ADD     M               ; UNPACKED BCD+30=ASCII
  184.         MOV     M,A             ; PUT CORRECTED ANSWER BACK
  185.         INX     H               ; NEXT DIGIT
  186.         DCR     B               ; DONE ?
  187.         JNZ     FILL            ;
  188.         LHLD    SAVEHL          ; OLD HL POINTER (VERY OLD)
  189.         MOV     A,M             ; LET'S DO A LITTLE ERROR 
  190.                                 ; CHECKING
  191.         CPI     0AH             ;
  192.         JNZ     ERROR           ; VARIABLE WRONG LENGTH
  193.         INX     H               ; NOW LET'S GIVE dBASE THE ANSWER
  194.         XCHG                    ; I KINDA LIKE THIS INSTRUCTION
  195.         LXI     H,ANSWER+1      ; SHOULD BE OBVIOUS BY NOW
  196.         MVI     B,0AH           ; COUNTER TO MOVE BYTES
  197. PASS:   MOV     A,M             ; GET BYTE
  198.         INX     H               ; FOR NEXT BYTE
  199.         XCHG                    ; WHERE TO SEND
  200.         MOV     M,A             ; SEND IT
  201.         INX     H               ; WHERE TO SEND NEXT ONE
  202.         XCHG                    ; BACK TO SOURCE POINTER
  203.         DCR     B               ; COUNTER FOR BYTES PASSED
  204.         JNZ     PASS            ; DO NEXT BYTE
  205.         JMP     FINIS           ; NORMAL END OF ROUTINE
  206. ERROR:  INX     H               ; POINT TO FIRST BYTE
  207.         MVI     A,'E'           ; ERROR CODE
  208.         MOV     M,A             ; SEND ERROR CODE TO DBASE
  209. FINIS:  LDA     SAVDSK          ; GET BACK DISK IN USE NO.
  210.         MOV     E,A             ; PUT IN E FOR BDOS CALL
  211.         MVI     C,FCHG          ; FUNCTION TO CHANGE DISK
  212.         CALL    BDOS            ; BACK TO ORIGINAL DRIVE
  213.         LHLD    SAVESP          ; RESTORE SP
  214.         SPHL                    ;
  215.         LHLD    SAVEHL          ; RESTORE HL
  216.         RET
  217. ;è;
  218. ;    SUBROUTINES FOR CALCULATIONS
  219. ;
  220. PUTBK:  ORA     A               ; CLEAR CARRY
  221.         MVI     B,04H           ; COUNTER FOR ADDS
  222. PUT1:   MOV     A,M             ; GET DATA
  223.         XCHG                    ; POINT TO SUB TABLE
  224.         ADC     M               ; ADD BACK IN AMMOUNT
  225.         INX     H               ; POINT TO NEXT SUB TABLE BYTE
  226.         XCHG                    ; BACK TO DATA POINTER
  227.         MOV     M,A             ; PUT BACK RESULT
  228.         INX     H               ; POINT TO NEXT DATA BYTE
  229.         DCR     B                       
  230.         JNZ     PUT1            ; NEXT BYTE
  231.         DCX     H               ; RESET DATA POINTER
  232.         DCX     H               ;
  233.         DCX     H               ;
  234.         DCX     H               ;
  235.         PUSH    H               ; SAVE HL
  236.         LXI     H,ANSWER        ; POINT TO SIG DIGIT POINTER
  237.         INR     M               ; INCREMENT TO NEXT DIGIT
  238.         POP     H               ; RESTORE HL
  239.         DCR     C               ; COUNT FOR SIG DIGITS DONE
  240.         RET                     ; RETURN TO CALLER
  241. ;
  242. AD1:    PUSH    PSW             ; SAVE REGISTERS
  243.         PUSH    B               ;
  244.         PUSH    D               ;
  245.         PUSH    H               ;                       
  246.         LXI     H,ANSWER        ; ANSWER TABLE
  247.         MOV     E,M             ; GET POSITION
  248.         MVI     D,00H           ; FOR VECTOR
  249.         DAD     D               ; VECTOR TO SIG DIGIT
  250.         INR     M               ; ADD 1 TO DIGIT
  251.         POP     H               ; RESTORE REGISTERS
  252.         POP     D               ;
  253.         POP     B               ;
  254.         POP     PSW             ;
  255.         RET                     ;
  256. SAVEHL: DS      2
  257. SAVESP: DS      2
  258. DPBADR: DS      2
  259. ALVLNG: DS      2
  260. BLS:    DS      2
  261. TEMP:   DS      2
  262. SAVDSK: DS      1
  263. ;
  264. TABLE:  DB      00H
  265.         DB      04H
  266.         DB      00H
  267.         DB      08H
  268.         DB      00H
  269.         DB      10H
  270.         DB      00Hè        DB      20H
  271.         DB      00H
  272.         DB      40H
  273. ;
  274. SIZE0:   DS     2
  275. SIZE1:   DS     2
  276. ;
  277. ;
  278. ANSWER: DS      10H             ; TOTAL SIG DIGITS+POINTER
  279. ;
  280. TBL2:   DB      000H,0CAH,09AH,03BH
  281.         DB      000H,0E1H,0F5H,005H
  282.         DB      080H,096H,098H,000H
  283.         DB      040H,042H,00FH,000H
  284.         DB      0A0H,086H,001H,000H
  285.         DB      010H,027H,000H,000H
  286.         DB      0E8H,003H,000H,000H
  287.         DB      064H,000H,000H,000H
  288.         DB      00AH,000H,000H,000H
  289.         DB      001H,000H,000H,000H
  290. ;
  291. END
  292.